﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StoreTransport.DAO;
using StoreTransport.DTO;
using StoreTransport.Business.Helper;
using StoreTransport.Business.Constants;

namespace StoreTransport.Business.Services {
    public class ProductOrderService {
        public static List<ProductOrderDTO> BuildProductOrdersList(int productLineID) {
            //Get ProductOrder by line
            StoreTransportDataContext context = CommonHelper.GetContext();
            var productOrdersByCode = context.ProductOrders.Where(c => c.ProductLineId == productLineID);
            if (productOrdersByCode.Count() == 0) {
                return null;
            }
            //remove product in active
            var productIdList = productOrdersByCode.Select(c => c.ProductId);
            var validStatus = Status.A.ToString()[0];
            List<int> validProductIds = context.Products.Where(c => productIdList.Contains(c.ID) &&
                c.Status == validStatus).Select(c => c.ID).ToList();
            var productOrdersByKind = productOrdersByCode.Where(c => validProductIds.Contains(c.ProductId)).
                GroupBy(c => c.ProductKindId);

            //get productKind 
            var productKindIds = productOrdersByCode.Select(c => c.ProductKindId).Distinct();
            var productKindList = context.ProductKinds.Where(c => productKindIds.Contains(c.ID));

            //get product line Item info -> last import date, number warning day
            ProductLine pl = context.ProductLines.Where(c => c.ID == productLineID).First();
            int numberWarningDay = pl.DefaultWarningDays;
            DateTime lastImportDate = pl.LastUpdatedDate;
            int numberStoreDays = pl.StandardStoreDays;

            DateTime orderDate = DateTime.MinValue;
            // calculate to find the max order date by Kind.
            List<ProductOrderDTO> productOrderList = new List<ProductOrderDTO>();
            foreach (var kind in productOrdersByKind) {
                var sumSaleRate = kind.Sum(c => c.SumSaleRate);
                if (sumSaleRate <= 0) {
                    continue;
                }
                var sumComputed = kind.Sum(c => c.ComputedInventory);
                var productkind = productKindList.Where(c => c.ID == kind.Key).First();
                int productRecieve = productkind.NumberReceiveProduct.HasValue ? productkind.NumberReceiveProduct.Value : 0;
                // so ngay con co the ban
                int sellDayLeft = Convert.ToInt32(((sumComputed + productRecieve) / (double)sumSaleRate) - 0.5);

                DateTime warningDate = lastImportDate.
                    AddDays(sellDayLeft - numberWarningDay - numberStoreDays);
                ProductOrderDTO order = new ProductOrderDTO();
                order.ProductKindName = productkind.ProductKindName;
                order.SumInventoryNumber = kind.Sum(c => c.ImportInventory);
                order.SumSaleRate = (double)sumSaleRate;
                order.SumComputedNumber = sumComputed;
                order.numberWarningDay = numberWarningDay;
                order.WarningDate = warningDate;
                order.OrderDays = pl.OrderDayNumber;
                order.NumberStoreDays = numberStoreDays;
                order.NumberRecieveProduct = productkind.NumberReceiveProduct.HasValue? productkind.NumberReceiveProduct.Value : 0;
                productOrderList.Add(order);
            }
            return productOrderList.OrderBy(c => c.ProductKindName).ToList();
        }

        public static bool ShowOrderProductWarning(int productLineID) {
            List<ProductOrderDTO> orderList = BuildProductOrdersList(productLineID);
            DateTime orderDate = DateTime.MaxValue;
            if (orderList != null && orderList.Count > 0) {
                foreach (var order in orderList) {
                    if (orderDate > order.WarningDate) {
                        orderDate = order.WarningDate;
                    }
                }
            }
            return DateTime.Today >= orderDate;
        }
    }
}
